package xin.nick.system.manager;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import xin.nick.system.entity.SystemRole;
import xin.nick.system.entity.SystemUserRole;
import xin.nick.system.mapper.SystemRoleMapper;
import xin.nick.system.mapper.SystemUserRoleMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Nick
 * @since 2022/8/11
 */
@Component
@RequiredArgsConstructor
public class SystemRoleManager {


    private final SystemRoleMapper roleMapper;
    private final SystemUserRoleMapper userRoleMapper;


    /**
     * 获取角色列表
     *
     * @return List<SystemRole>
     */
    public List<SystemRole> getRoleList() {
        return roleMapper.selectList(Wrappers.emptyWrapper());
    }


    /**
     * 获取角色Map
     *
     * @return Map<Long, SystemRole>
     */
    public Map<Long, SystemRole> getRoleMap() {

        List<SystemRole> roleList = getRoleList();

        return roleList.stream()
                .filter(Objects::nonNull)
                .filter(role -> Objects.nonNull(role.getRoleId()))
                .collect(Collectors.toMap(SystemRole::getRoleId, Function.identity(), (v1, v2) -> v2));
    }

    /**
     * 获取所有角色id列表
     *
     */
    public List<Long> getRoleIdList() {
        List<SystemRole> roleList = getRoleList();
        return roleList.stream()
                .filter(Objects::nonNull)
                .map(SystemRole::getRoleId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 获取存在的角色id
     *
     * @param filterRoleIdList List<Long>
     * @return List<Long>
     */
    public List<Long> filterExistingIdList(List<Long> filterRoleIdList) {
        if (CollectionUtils.isEmpty(filterRoleIdList)) {
            return new ArrayList<>();
        }

        List<Long> roleIdList = getRoleIdList();
        return filterRoleIdList.stream()
                .filter(Objects::nonNull)
                .filter(roleIdList::contains)
                .collect(Collectors.toList());
    }

    /**
     * 更新用户角色关联
     *
     * @param userId Long
     * @param roleIdList List<Long>
     */
    public void updateUserRoleList(Long userId, List<Long> roleIdList) {

        if (CollectionUtils.isEmpty(roleIdList)) {
            roleIdList = new ArrayList<>();
        }
        roleIdList = roleIdList.stream().filter(Objects::nonNull).collect(Collectors.toList());
        Assert.notNull(userId, "用户id为空");

        // 删除原来的角色关联
        userRoleMapper.delete(Wrappers.<SystemUserRole>lambdaQuery().eq(SystemUserRole::getUserId, userId));
        // 插入新的角色关联
        for (Long roleId : roleIdList) {
            SystemUserRole userRole = new SystemUserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleMapper.insert(userRole);
        }
    }

    /**
     * 根据用户id获取角色列表
     *
     * @param userId Long
     * @return List<SystemRole>
     */
    public List<SystemRole> getRoleListByUserId(Long userId) {

        // think 下面是不是直接通过SQL查询会快一些

        // 根据用户获取角色关联id
        List<SystemUserRole> userRoleList = userRoleMapper.selectList(Wrappers.<SystemUserRole>lambdaQuery().eq(SystemUserRole::getUserId, userId));
        if (CollUtil.isEmpty(userRoleList)) {
            return new ArrayList<>();
        }
        List<Long> roleIdList = userRoleList.stream()
                .filter(Objects::nonNull)
                .map(SystemUserRole::getRoleId)
                .filter(Objects::nonNull).collect(Collectors.toList());
        if (CollUtil.isEmpty(roleIdList)) {
            return new ArrayList<>();
        }

        // 去数据库获取角色信息,并返回
        return roleMapper.selectList(
                        Wrappers.<SystemRole>lambdaQuery()
                                .in(SystemRole::getRoleId, roleIdList))
                .stream().filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 根据用户id获取角色id列表
     *
     * @param userId Long
     * @return List<Long>
     */
    public List<Long> getRoleIdListByUserId(Long userId) {

        if (Objects.isNull(userId)) {
            return new ArrayList<>();
        }

        return getRoleListByUserId(userId).stream()
                .filter(Objects::nonNull).map(SystemRole::getRoleId).filter(Objects::nonNull)
                .collect(Collectors.toList());
    }
}
